
#include "loaded_file.h"

#include <stdio.h>
#include <iostream>
#include <fstream>

#include "main_container.h"
#include "errors_warnings.h"
extern MainContainer * CompilerData;

LoadedFile::~LoadedFile() {
	if(fileName != NULL)	{
		delete fileName;
		fileName = NULL;
	}
	if(sourceLines != NULL)	{
		delete sourceLines;
		sourceLines = NULL;
	}
}


LoadedFile::LoadedFile(const char * fileName, int id) {
#ifdef TRACE
	CompilerData->LogTrace->ReportEntry("LoadedFile::LoadedFile");
	CompilerData->LogTrace->ReportLine("Reading file with parameters...");
	CompilerData->LogTrace->ReportValue("fileName", fileName);
	CompilerData->LogTrace->ReportValue("id", id);
#endif

	this->currentColumn = 0;
	this->currentRow = 0;
	this->fileID = id;
	this->fileName = new char[strlen(fileName)];
	strcpy(this->fileName, fileName);
	this->sourceLines = new GenericTable<SourceLine>();
	// open file
	ifstream currentFile;
	currentFile.open(fileName, ios_base::in);
	// if file can't be opened...
	if( ! currentFile.is_open())	{
#ifdef TRACE
		CompilerData->LogTrace->ReportExit("LoadedFile::LoadedFile");
#endif
		return;
	}
	while(!currentFile.eof())	{
		// copy line per line of the file to memory
		char * newLine = new char[MAX_LENGTH_FILE_LINE];
		currentFile.getline(newLine, MAX_LENGTH_FILE_LINE);
		strcat(newLine, "\n");
		SourceLine * sl = new SourceLine(newLine);
		this->sourceLines->Add(sl);
		delete[] newLine;
	}
#ifdef TRACE
	CompilerData->LogTrace->ReportExit("LoadedFile::LoadedFile");
#endif
}

int LoadedFile::GetCurentFileID() {
	return fileID;
}

int LoadedFile::GetCurrentColumn() {
	return currentColumn;
}

int LoadedFile::GetCurrentLine() {
	return currentRow;
}


int LoadedFile::MoveFor(int count) {
	int absCount = count > 0 ? count : -count;
	for (int i = 0; i < absCount; i++)	{
		if (count > 0)	currentColumn++;
		else	currentColumn--;
		SourceLine * sl = sourceLines->GetData(currentRow);
		if(currentColumn < 0)	{
			currentRow--;
			if(currentRow < 0)	{
				currentRow = 0;
				currentColumn = 0;
				return -1;
			}
			sl = sourceLines->GetData(currentRow);
			currentColumn = (int)strlen(sl->lineCharacters) - 1;
		}
		else if(currentColumn >= (int)strlen(sl->lineCharacters))	{
			currentRow++;
			if(currentRow < sourceLines->GetCount())	currentColumn = 0;
			else	{
				// currentRow++; // TODO - possible BUG
				currentColumn--;
				return 1;
			}
		}
	}
	return 0;
}


int LoadedFile::GetNextCharacter() {
	int retVal = LookNextCharacter();
	if(MoveFor(1) != 0)	{
		retVal = -1;
	}
	return retVal;
}


int LoadedFile::LookNextCharacter() {
	int retVal;
	try	{
		SourceLine * sl = sourceLines->GetData(currentRow);
		if(sl)	retVal = sl->lineCharacters[currentColumn];
		else	retVal = -1;
	}
	catch(...)	{
		retVal = -1;
	}
	// to make EOF properly - TODO enhance this
	if((retVal == 0 && strlen(sourceLines->GetData(currentRow)->lineCharacters) > 0) ||
		  (currentRow >= sourceLines->GetCount()) ||
		  ((currentRow == sourceLines->GetCount() - 1) 
		  && (currentColumn >= (int)strlen(sourceLines->GetData(currentRow)->lineCharacters)) ))	{
		retVal = -1;
	}
	else if(retVal == 0 && strlen(sourceLines->GetData(currentRow)->lineCharacters) == 0)	retVal = ' ';
	return retVal;
}

int LoadedFile::RewindCharacter() {
	MoveFor(-1);
	int retVal = LookNextCharacter();
	return retVal;
}

int LoadedFile::RewindCharacter(int count) {
	MoveFor(-count);
	int retVal = LookNextCharacter();
	return retVal;
}


void LoadedFile::RewindToBeginning() {
	currentColumn = 0;
	currentRow = 0;
}
